#pragma once
#ifdef _MSC_VER
#	ifdef csv_STATIC_LIB
#		define csv_SDK_API_
#	elif defined SDK_EXPORTS
#		define csv_SDK_API_ __declspec(dllexport)
#	else
#		define csv_SDK_API_ __declspec(dllimport)
#	endif
#else /* _MSC_VER */
#	ifdef SDK_EXPORTS
#		define csv_SDK_API_ __attribute__((visibility ("default")))
#	else
#		define csv_SDK_API_
#	endif
#endif

#ifdef __cplusplus
#	define csv_SDK_API extern "C" csv_SDK_API_
#else
#	define csv_SDK_API csv_SDK_API_
#endif
#include "TargetRecognition.h"

typedef void* csv_alarmer_handle_t;

#ifdef OIL
#define CLASS_OFFSET 0
#endif

#ifdef HAIER
#define CLASS_OFFSET 6
#endif // HAIER_UNIFORM

enum alarm_type {
    ALARM_VEHICLE,
    ALARM_EXTINGUISHER,
    ALARM_PERSON,
    ALARM_OUTSIDER,
    ALARM_STAFFPOST,
};
enum alarm_postivity {
    BOTH,
    POSITIVE,
    NEGATIVE,  
};



typedef struct vehicle_rule {
    int run_status = -1;
    std::vector<csv_rect_t> rects = {};             //矩形报警区域
    std::vector<csv_point_t> poly = {};             //多边形报警区域
    csv_rect_t park_area;                           //停车区域
    int alarm_interval = -1;                        //报警间隔，单位秒
    bool is_stricted_interval = false;              //是否严格按照报警间隔报警，是代表即便没有目标也会在间隔后上报；否代表在间隔内出现新目标会上报，没目标不上报
    int confidence_threshold = 128;                 //报警置信度阈值，取值0-100
    float park_ratio = 0.95;                        //停车重合度，取值0-1
    int postivity = BOTH;                           //报警正负性，默认是否入位都报警，POSITIVE代表入位报警，NEGATIVE代表未入位报警
}vehicle_rule;

typedef struct person_rule {
    int run_status = -1;
    std::vector<csv_rect_t> rects = {};             //矩形报警区域
    std::vector<csv_point_t> poly = {};             //多边形报警区域
    int alarm_interval = -1;                        //报警间隔，单位秒
    bool is_stricted_interval = false;              //是否严格按照报警间隔报警，是代表即便没有目标也会在间隔后上报；否代表在间隔内出现新目标会上报，没目标不上报
    int confidence_threshold = 128;                 //报警置信度阈值，取值0-100
    int hat_threshold = 128;                     //人员头盔置信度阈值
    int cloth_threshold = 128;                   //人员工服置信度阈值
    int hat_postivity = BOTH;                    
    int cloth_postivity = BOTH;
    
}person_rule;

typedef struct outsider_rule {
    int run_status = -1;
    std::vector<csv_rect_t> rects = {};             //矩形报警区域
    std::vector<csv_point_t> poly = {};             //多边形报警区域
    int alarm_interval = -1;                        //报警间隔，单位秒
    bool is_stricted_interval = false;              //是否严格按照报警间隔报警，是代表即便没有目标也会在间隔后上报；否代表在间隔内出现新目标会上报，没目标不上报
    int confidence_threshold = 128;                 //报警置信度阈值，取值0-100
    int max_outsider_num = -1;                      //最大外人数量
    int postivity = BOTH;
}outsider_rule;

typedef struct staffpost_rule {
    int run_status = -1;
    std::vector<csv_rect_t> rects = {};             //矩形报警区域
    std::vector<csv_point_t> poly = {};             //多边形报警区域
    int alarm_interval = -1;                        //报警间隔，单位秒
    bool is_stricted_interval = false;              //是否严格按照报警间隔报警，是代表即便没有目标也会在间隔后上报；否代表在间隔内出现新目标会上报，没目标不上报
    int max_staff_leave_time = -1;                  //最大离岗时间
    int min_staff_num = -1;                         //最少员工数量
    int confidence_threshold = 128;                 //报警置信度阈值，取值0-100
    int postivity = BOTH;
}staffpost_rule;


typedef struct extinguisher_rule {
    int run_status = -1;
    std::vector<csv_rect_t> rects = {};             //矩形报警区域
    std::vector<csv_point_t> poly = {};             //多边形报警区域
    int alarm_interval = -1;                        //报警间隔，单位秒
    bool is_stricted_interval = false;              //是否严格按照报警间隔报警，是代表即便没有目标也会在间隔后上报；否代表在间隔内出现新目标会上报，没目标不上报
    int confidence_threshold = 128;                 //报警置信度阈值，取值0-100
    int postivity = BOTH;
}extinguisher_rule;

typedef struct rule_set {
    vehicle_rule v_rule;
    person_rule p_rule;
    outsider_rule o_rule;
    staffpost_rule s_rule;
    extinguisher_rule e_rule;
}rule_set;


typedef struct vehicle_alarm {
    csv_rect_t target_rect;                           //目标位置
    int confidence = 0;                               //目标置信度
    int in_park_area = -1;                            //是否入位，1表示入位，0表示未入位
}vehicle_alarm;

typedef struct person_alarm {
    csv_rect_t target_rect;                           //目标位置
    int confidence = 0;                               //目标置信度
    int helmet_confidence = 0;                        //人员头盔置信度
    int helmet_type = -1;                             //头盔检测种类，-1代表未检测或未能检测出，0表示未佩戴，1表示佩戴
    int overall_confidence = 0;                       //人员工服置信度
    int overall_type = -1;                            //工服检测种类，-1代表未检测或未能检测出，0表示未穿戴，1表示穿戴
    int ID = -1;
    bool null_vec = false;
}person_alarm;

typedef struct outsider_alarm {
    csv_rect_t target_rect;                           //目标位置
    int confidence = 0;                               //目标置信度
}outsider_alarm;

typedef struct staffpost_alarm {
    int staff_leave_time = -1;                       //累计离岗时间
}staffpost_alarm;

typedef struct extinguisher_alarm {
    csv_rect_t target_rect;                           //目标位置
    int confidence = 0;                               //目标置信度
}extinguisher_alarm;

typedef struct alarm_set {
    std::vector<vehicle_alarm> v_alarms;

    std::vector<person_alarm> p_alarms;

    std::vector<outsider_alarm> o_alarms;

    std::vector<extinguisher_alarm> e_alarms;

    staffpost_alarm s_alarm;

}alarm_set;

csv_SDK_API
void csv_create_alarmer(void** handle);     //创建报警分析句柄

csv_SDK_API
void csv_add_rule(void* handle, rule_set rules);    //添加/更新报警规则

csv_SDK_API
void csv_control_rule(void* handle, alarm_type type, int open);
csv_SDK_API
void csv_delete_rule(void* handle, alarm_type type);  //删除报警规则
csv_SDK_API
bool csv_box_in_area(csv_rect_t box, std::vector<csv_rect_t>rects,float iou_threshold);  //判断box是否在rects区域内，可用于三角木等图片检测
csv_SDK_API
int csv_alarmer_init_time(void* handle);   //初始化时间，用于给报警间隔计时，在初次检测前初始化

csv_SDK_API
void  csv_analyse(void* handle, csv_target_t* p_target_array, int target_num, alarm_set& alarms);